home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XAAES_S.ZIP / XAAES / OBJECTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  30.3 KB  |  1,137 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #ifdef LATTICE
  10. #undef abs        /* MiNTlib (PL46) #define is buggy! */
  11. #define abs(i)    __builtin_abs(i)
  12. #endif
  13. #include "XA_DEFS.H"
  14. #include "XA_TYPES.H"
  15. #include "XA_GLOBL.H"
  16. #include "K_DEFS.H"
  17. #include "RECTLIST.H"
  18. #include "BOX3D.H"
  19. #include "objects.h"
  20.  
  21. /*
  22.     OBJECT TREE ROUTINES
  23. */
  24.  
  25. const short selected_colour[]={1,0,13,15,14,10,12,11,8,9,5,7,6,2,4,3};
  26. const short selected3D_colour[]={1,0,13,15,14,10,12,11,9,8,5,7,6,2,4,3};
  27.  
  28. short global_clip[4];    /* Bloody progdefs need to know the clip rectangle */
  29.  
  30. void set_clip(short x, short y, short w, short h)
  31. {
  32.     global_clip[0]=x;
  33.     global_clip[1]=y;
  34.     global_clip[2]=x+w-1;
  35.     global_clip[3]=y+h-1;
  36.     vs_clip(V_handle,1,global_clip);
  37. }
  38.  
  39. /* Set clipping to entire screen */
  40. void clear_clip(void)
  41. {
  42.     global_clip[0]=display.x;
  43.     global_clip[1]=display.y;
  44.     global_clip[2]=display.x+display.w-1;
  45.     global_clip[3]=display.y+display.h-1;
  46.     vs_clip(V_handle,1,global_clip);
  47. }
  48.  
  49. /*
  50.     Draw a 2d box outline (allows 'proper' thickness - 1,2,3,etc)
  51.     Note: expects writing mode to be set up by caller.
  52. */
  53. void draw_2d_box(short x, short y, short w, short h, short border_thick, short colour)
  54. {
  55.     short coords[4];
  56.     short vo;
  57.     
  58.     if (border_thick<0)
  59.     {
  60.         border_thick++;
  61.         vo=-border_thick-1;
  62.     }else{
  63.         border_thick--;
  64.         vo=border_thick+1;
  65.     }
  66.  
  67.     if (border_thick>5)
  68.         border_thick=0;
  69.  
  70.     vsf_interior(V_handle, FIS_SOLID);
  71.     vsf_color(V_handle, colour);
  72.             
  73.     coords[0]=x;
  74.     coords[1]=y-vo;
  75.     coords[2]=x+border_thick;
  76.     coords[3]=y+h+vo;
  77.     v_bar(V_handle, coords);
  78.     coords[0]=x+w;
  79.     coords[1]=y-vo;
  80.     coords[2]=x+w-border_thick;
  81.     coords[3]=y+h+vo;
  82.     v_bar(V_handle, coords);
  83.     coords[0]=x;
  84.     coords[1]=y;
  85.     coords[2]=x+w;
  86.     coords[3]=y+border_thick;
  87.     v_bar(V_handle, coords);
  88.     coords[0]=x;
  89.     coords[1]=y+h;
  90.     coords[2]=x+w;
  91.     coords[3]=y+h-border_thick;
  92.     v_bar(V_handle, coords);
  93.  
  94. }
  95.  
  96. /*
  97.     Format a G_FTEXT type text string from it's template,
  98.     and return the real position of the text cursor in this
  99. */
  100. short format_dialog_text(char *text_out, char *template, char *text_in,short edit_pos)
  101. {
  102.     short index=0,edit_index,tpos=0;
  103.     
  104.     while(*template)
  105.     {
  106.         switch(*template)
  107.         {
  108.             case '_':                /* Found text field */
  109.                 if (tpos==edit_pos)
  110.                     edit_index=index;
  111.                 
  112.                 if (*text_in)
  113.                 {
  114.                     *text_out=*text_in;
  115.                     text_in++;
  116.                 }else{
  117.                     *text_out='_';
  118.                 }
  119.                 tpos++;
  120.                 
  121.                 text_out++;
  122.                 template++;
  123.                 break;
  124.             default:                /* Formatting characters */
  125.                 *text_out=*template;
  126.                 text_out++;
  127.                 template++;
  128.                 break;
  129.         }
  130.         index++;
  131.     }
  132.     *text_out='\0';
  133.     
  134.     return edit_index;
  135. }
  136.  
  137. /*
  138.     Display a primitive object
  139. */
  140. void display_object(OBJECT *tree,short object,short parent_x,short parent_y)
  141. {
  142.     unsigned long ob_spec;
  143.     OBJC_COLORWORD *colourword;
  144.     OBJECT *ob=tree+object;
  145.     unsigned short t,zap;
  146.     short border_thick=0,coords[10];
  147.     short temp,icx,icy,cols[2];
  148.     TEDINFO *textblk;
  149.     ICONBLK *iconblk;
  150.     CICONBLK *ciconblk;
  151.     CICON    *this_cicon;
  152.     CICON    *best_cicon;
  153.     BITBLK *bitblk;
  154.     MFDB Mscreen;
  155.     MFDB Micon;
  156.     short msk_col,icn_col,x;
  157.     char temp_text[200];
  158.     short tx,ty,txt_curs,tw,th;
  159.     short selected;
  160.     short colourmode=(display.colours>=16) ;
  161.     short state_mask=(SELECTED|CROSSED|CHECKED|DISABLED); /* -> G_PROGDEF */
  162.     short obx=parent_x+ob->ob_x;
  163.     short oby=parent_y+ob->ob_y;
  164.     short obx2=obx+ob->ob_width-1;
  165.     short oby2=oby+ob->ob_height-1;
  166.  
  167.     if ((obx>global_clip[2])            /* Exit immediately if object is totally outside clip area */
  168.         ||((obx2<global_clip[0])
  169.         ||((oby>global_clip[3])
  170.         ||(oby2<global_clip[1]))))
  171.     {
  172.         return;
  173.     }
  174.  
  175.     ob_spec=(unsigned long)ob->ob_spec;
  176.     t=(ob->ob_type)&0xff;
  177.     selected=ob->ob_state&SELECTED;
  178.         
  179.     colourword=(OBJC_COLORWORD*)&zap;
  180.  
  181.     if ((ob->ob_flags&DEFAULT) &&    /* Default exit object */
  182.         (t==G_BUTTON) &&                /* Only BUTTONS change appearance! */
  183.         (ob->ob_flags&FLD3DANY))    /* 2D buttons are handled elsewhere */
  184.     {
  185.         vsf_color(V_handle,BLACK);
  186.         vsf_interior(V_handle, FIS_SOLID);
  187.         coords[0]=parent_x+ob->ob_x-2;
  188.         coords[1]=parent_y+ob->ob_y-2;
  189.         coords[2]=coords[0]+ob->ob_width+3;
  190.         coords[3]=coords[1]+ob->ob_height+3;
  191.         v_bar(V_handle, coords);
  192.     }
  193.  
  194.     switch(t)    /* Sort out the colourword */
  195.     {
  196.         case G_BOXCHAR:
  197.             temp_text[0]=(ob_spec&0xff000000L)>>24;
  198.             temp_text[1]='\0';
  199.             zap=(unsigned short)ob->ob_spec&0xffff;
  200.             border_thick=(short)((ob_spec&0xff0000L)>>16);
  201.             if (border_thick&128)
  202.                 border_thick=-(1+(border_thick^0xff));
  203.             break;
  204.             
  205.         case G_BOX:
  206.         case G_IBOX:
  207.             zap=(unsigned short)ob->ob_spec&0xffff;
  208.             border_thick=(short)((ob_spec&0xff0000L)>>16);
  209.             if (border_thick&128)
  210.                 border_thick=-(1+(border_thick^0xff));
  211.             break;
  212.             
  213.         case G_FTEXT:
  214.         case G_FBOXTEXT:
  215.         case G_TEXT:
  216.         case G_BOXTEXT:
  217.             textblk=(TEDINFO*)ob->ob_spec;
  218.             zap=(unsigned short)textblk->te_color;
  219.             border_thick=textblk->te_thickness;
  220.  
  221.             if (ob->ob_state&IS_EDIT)
  222.                 txt_curs=textblk->te_tmplen;
  223.             
  224.             switch(textblk->te_just)            /*Set text alignment - why on earth did */
  225.             {                                    /* atari use a different horizontal alignment */
  226.                 case 0:                            /* code for GEM to the one the VDI uses? */
  227.                     vst_alignment(V_handle,0,5,&temp,&temp);
  228.                     break;
  229.                 case 1:
  230.                     vst_alignment(V_handle,2,5,&temp,&temp);
  231.                     break;
  232.                 case 2:
  233.                     vst_alignment(V_handle,1,5,&temp,&temp);
  234.                     break;
  235.             }
  236.             
  237.             switch(textblk->te_font)    /* Set the correct text size & font */
  238.             {
  239.                 case TE_GDOS_PROP:        /* Use a proportional SPEEDOGDOS font (AES4.1 style) */
  240.                 case TE_GDOS_MONO:        /* Use a monospaced SPEEDOGDOS font (AES4.1 style) */
  241.                 case TE_GDOS_BITM:        /* Use a GDOS bitmap font (AES4.1 style) */
  242.                     vst_font(V_handle,textblk->te_fontid);
  243.                     vst_point(V_handle,textblk->te_fontsize,&temp,&temp,&temp,&temp);
  244.                     tw=display.c_max_w;
  245.                     th=display.c_max_h;
  246.                     ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_max_h)/2);
  247.                     break;
  248.                 case TE_STANDARD:        /* Use the standard system font (probably 10 point) */
  249.                     vst_font(V_handle,display.standard_font_id);
  250.                     vst_point(V_handle,display.standard_font_point,&temp,&temp,&temp,&temp);
  251.                     tw=display.c_max_w;
  252.                     th=display.c_max_h;
  253.                     ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_max_h)/2);
  254.                     break;
  255.                 case TE_SMALL:            /* Use the small syatem font (probably 8 point) */
  256.                     vst_font(V_handle,display.small_font_id);
  257.                     vst_point(V_handle,display.small_font_point,&temp,&temp,&temp,&temp);
  258.                     tw=display.c_min_w;
  259.                     th=display.c_min_h;
  260.                     ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_min_h)/2);
  261.                     break;
  262.             }
  263.             
  264.             vst_color(V_handle, colourword->textc);
  265.  
  266.             break;
  267.             
  268.         case G_BUTTON:
  269.             zap=0x11f8;
  270.             /* Negative border thickness - outside border! */
  271.             border_thick=-1;
  272.             if (ob->ob_flags&EXIT)
  273.                 border_thick--;
  274.             if (ob->ob_flags&DEFAULT)
  275.                 border_thick--;
  276.             ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_max_h)/2);
  277.             break;
  278.             
  279.         case G_STRING:
  280.             zap=0x0100;
  281.             ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_max_h)/2);
  282.             break;
  283.             
  284.         case G_CICON:
  285.             ciconblk=(CICONBLK*)ob->ob_spec;
  286.  
  287.             best_cicon=NULL; this_cicon=ciconblk->mainlist;
  288.             while(this_cicon)
  289.             {
  290.                 if ((this_cicon->num_planes<=display.planes)
  291.                     &&((!best_cicon)||(this_cicon->num_planes>best_cicon->num_planes)))
  292.                 {
  293.                         best_cicon=this_cicon;
  294.                 }
  295.                 
  296.                 this_cicon=this_cicon->next_res;    
  297.             }
  298.             
  299.             if (!best_cicon)                            /* No matching icon, so use the mono one instead */
  300.             {
  301.                 t=G_ICON;
  302.             }else{
  303.                 this_cicon=best_cicon;
  304.             }
  305.             
  306.             iconblk=(ICONBLK*)ob->ob_spec;
  307.             break;
  308.             
  309.         case G_ICON:
  310.             iconblk=(ICONBLK*)ob->ob_spec;
  311.             break;
  312.             
  313.         case G_IMAGE:
  314.             bitblk=(BITBLK*)ob->ob_spec;
  315.             zap=(unsigned short)bitblk->bi_color;
  316.             colourword->pattern=7;
  317.             break;
  318.     }
  319.  
  320.     /*    Are we shadowing this object? (Borderless objects aren't shadowed!) */
  321.     if (border_thick && (ob->ob_state&SHADOWED))
  322.     {
  323.         short offset, increase;
  324.  
  325.         if (border_thick>0)
  326.             { offset=border_thick ; increase=border_thick-1 ; }
  327.         else
  328.             { offset=0 ; increase=-3*border_thick-1 ; }
  329.  
  330.         vsf_color(V_handle,colourword->borderc);
  331.         vsf_interior(V_handle, FIS_SOLID);
  332.         coords[0]=parent_x+ob->ob_x+offset;
  333.         coords[1]=parent_y+ob->ob_y+offset;
  334.         coords[2]=coords[0]+ob->ob_width+increase;
  335.         coords[3]=coords[1]+ob->ob_height+increase;
  336.         v_bar(V_handle, coords);
  337.     }
  338.  
  339.     /* Note: `colourword->opaque' applies *only* to the text
  340.         part of an object!!!!!! */
  341.     vswr_mode(V_handle, MD_REPLACE);
  342.  
  343.     vsf_interior(V_handle, FIS_PATTERN);
  344.     if (colourword->pattern==7)
  345.     {
  346.         vsf_style(V_handle, 8);
  347.     }else{
  348.         if (colourword->pattern==0)
  349.         {
  350.             vsf_style(V_handle, 8);
  351.             if ((colourword->fillc==0)&&(ob->ob_flags&FLD3DANY))    /* Object inherits default dialog background colour? */
  352.             {
  353.                 vswr_mode(V_handle, MD_TRANS);
  354.                 colourword->fillc=display.dial_colours.bg_col;
  355.             }else{
  356.                 colourword->fillc=WHITE;
  357.             }
  358.         }else{
  359.             vsf_style(V_handle, colourword->pattern);
  360.         }
  361.     }
  362.  
  363.     if (colourmode && selected)
  364.     {
  365.         if (ob->ob_flags&FLD3DANY)        /* Allow a different colour set for 3d push  */
  366.             vsf_color(V_handle, selected3D_colour[colourword->fillc]);
  367.         else
  368.             vsf_color(V_handle, selected_colour[colourword->fillc]);
  369.     }else{
  370.         vsf_color(V_handle, colourword->fillc);
  371.     }
  372.     
  373.     vsf_perimeter(V_handle, 0);
  374.     
  375.     switch(t)
  376.     {
  377.         case G_PROGDEF:    /* Not sure about this code..... */
  378.             {
  379.                 APPLBLK *ab=(APPLBLK*)ob->ob_spec;
  380.                 PARMBLK p;
  381.             
  382.                 p.pb_tree=tree;
  383.                 p.pb_obj=object;
  384.                 
  385.                 p.pb_prevstate=p.pb_currstate=ob->ob_state;
  386.                 
  387.                 p.pb_x=parent_x+ob->ob_x;
  388.                 p.pb_y=parent_y+ob->ob_y;
  389.                 p.pb_w=ob->ob_width;
  390.                 p.pb_h=ob->ob_height;
  391.                 
  392.                 p.pb_xc=global_clip[0];
  393.                 p.pb_yc=global_clip[1];
  394.                 p.pb_wc=global_clip[2]-global_clip[0]+1;
  395.                 p.pb_hc=global_clip[3]-global_clip[1]+1;
  396.                 
  397.                 p.pb_parm=ab->ab_parm;
  398.             
  399.                 /* The PROGDEF function returns the ob_state bits that
  400.                     remain to be handled by the AES: */
  401.                 state_mask = (short)(*(ab->ab_code))(&p);
  402.                 /* BUG: SELECTED bit only handled in non-color mode!!! */
  403.                 /* (Not too serious I believe... <mk>) */
  404.             }
  405.             break;
  406.         case G_BOX:
  407.             if (ob->ob_flags&FLD3DANY)
  408.             {
  409.                 XA_3D_pushbutton(parent_x+ob->ob_x-1, parent_y+ob->ob_y-1, ob->ob_width+1, ob->ob_height+1, selected);
  410.             }else{
  411.                 coords[0]=parent_x+ob->ob_x;
  412.                 coords[1]=parent_y+ob->ob_y;
  413.                 coords[2]=coords[0]+ob->ob_width-1;
  414.                 coords[3]=coords[1]+ob->ob_height-1;
  415.                 v_bar(V_handle, coords);
  416.                 if (border_thick)            /* Display a border? */
  417.                 {
  418.                     draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y, 
  419.                                 ob->ob_width, ob->ob_height, 
  420.                                 border_thick, colourword->borderc);
  421.                 }
  422.             }
  423.             break;
  424.         case G_IBOX:                    /* G_IBOX is like a box but doesn't get filled. */
  425.             if (border_thick)            /* Display a border? */
  426.             {
  427.                 draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y, 
  428.                             ob->ob_width, ob->ob_height, 
  429.                             border_thick, colourword->borderc);
  430.             }
  431.             break;
  432.         case G_BOXCHAR:
  433.             tx=parent_x + ob->ob_x + ((ob->ob_width-display.c_max_w)/2);    /* Centre the text in the box */
  434.             ty=parent_y + ob->ob_y + ((ob->ob_height-display.c_max_h)/2);
  435.  
  436.             if (ob->ob_flags&FLD3DANY)
  437.             {
  438.                 XA_3D_pushbutton(parent_x+ob->ob_x-1, parent_y+ob->ob_y-1, ob->ob_width+1, ob->ob_height+1, selected);
  439.                 if (selected)
  440.                 {
  441.                     tx+=PUSH3D_DISTANCE; ty+=PUSH3D_DISTANCE;
  442.                 }
  443.             }else{
  444. /*                if (colourword->opaque)*/
  445.                 {
  446.                     coords[0]=parent_x+ob->ob_x;
  447.                     coords[1]=parent_y+ob->ob_y;
  448.                     coords[2]=coords[0]+ob->ob_width-1;
  449.                     coords[3]=coords[1]+ob->ob_height-1;
  450.                     v_bar(V_handle, coords);
  451.                 }
  452.                 if (border_thick)            /* Display a border? */
  453.                 {
  454.                     draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y, 
  455.                                 ob->ob_width, ob->ob_height,
  456.                                 border_thick, colourword->borderc);
  457.                 }
  458.             }
  459.             
  460.             vst_font(V_handle,display.standard_font_id);
  461.             vst_point(V_handle,display.standard_font_point,&temp,&temp,&temp,&temp);
  462.             vst_alignment(V_handle,0,5,&x,&x);
  463.             vst_color(V_handle, colourword->textc);
  464.             
  465.             vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  466.             v_gtext(V_handle,tx,ty,temp_text);
  467.             break;
  468.         case G_FBOXTEXT:
  469.             switch(textblk->te_just)
  470.             {
  471.                 case 0:
  472.                     tx=parent_x+ob->ob_x;
  473.                     break;
  474.                 case 1:
  475.                     tx=parent_x+ob->ob_x+ob->ob_width;
  476.                     break;
  477.                 case 2:
  478.                     tx=parent_x+ob->ob_x+(ob->ob_width/2);
  479.                     break;
  480.             }
  481.  
  482.             txt_curs=format_dialog_text(temp_text, textblk->te_ptmplt, textblk->te_ptext, textblk->te_tmplen);
  483.  
  484.             if (ob->ob_flags&FLD3DANY)
  485.             {
  486.                 XA_3D_pushbutton(parent_x+ob->ob_x-1, parent_y+ob->ob_y-1, ob->ob_width+1, ob->ob_height+1, selected);
  487.                 if (selected)
  488.                 {
  489.                     tx+=PUSH3D_DISTANCE; ty+=PUSH3D_DISTANCE;
  490.                 }
  491.                 vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  492.                 v_gtext(V_handle,tx,ty,temp_text);
  493.             }else{
  494. /*                if (colourword->opaque)*/
  495.                 {
  496.                     coords[0]=parent_x+ob->ob_x;
  497.                     coords[1]=parent_y+ob->ob_y;
  498.                     coords[2]=coords[0]+ob->ob_width-1;
  499.                     coords[3]=coords[1]+ob->ob_height-1;
  500.                     v_bar(V_handle, coords);
  501.                 }
  502.                 
  503.                 vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  504.                 v_gtext(V_handle,tx,ty,temp_text);
  505.  
  506.                 if (selected)
  507.                 {
  508.                     coords[0]=parent_x+ob->ob_x;
  509.                     coords[1]=parent_y+ob->ob_y;
  510.                     coords[2]=coords[0]+ob->ob_width-1;
  511.                     coords[3]=coords[1]+ob->ob_height-1;
  512.                     vswr_mode(V_handle,MD_XOR);
  513.                     vsf_color(V_handle,BLACK);
  514.                     vsf_interior(V_handle,FIS_SOLID);
  515.                     v_bar(V_handle, coords);
  516.                 }
  517.                 
  518.                 if (border_thick)    /* Display a border? */
  519.                 {
  520.                     vswr_mode(V_handle, MD_REPLACE);
  521.                     draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y, 
  522.                                 ob->ob_width, ob->ob_height, 
  523.                                 border_thick, colourword->borderc);
  524.                 }
  525.             }
  526.             
  527.             if (ob->ob_state&IS_EDIT)
  528.             {
  529.                 coords[0]=parent_x+ob->ob_x+txt_curs*tw;
  530.                 coords[1]=parent_y+ob->ob_y;
  531.                 coords[2]=coords[0]+tw-1;
  532.                 coords[3]=coords[1]+th-1;
  533.                 vswr_mode(V_handle,MD_XOR);
  534.                 vsf_color(V_handle,BLACK);
  535.                 vsf_interior(V_handle,FIS_SOLID);
  536.                 v_bar(V_handle, coords);
  537.             }
  538.  
  539.             break;
  540.         case G_BOXTEXT:
  541.             switch(textblk->te_just)
  542.             {
  543.                 case 0:
  544.                     tx=parent_x+ob->ob_x;
  545.                     break;
  546.                 case 1:
  547.                     tx=parent_x+ob->ob_x+ob->ob_width;
  548.                     break;
  549.                 case 2:
  550.                     tx=parent_x+ob->ob_x+(ob->ob_width/2);
  551.                     break;
  552.             }
  553.             if (ob->ob_flags&FLD3DANY)
  554.             {
  555.                 XA_3D_pushbutton(parent_x+ob->ob_x-1, parent_y+ob->ob_y-1, ob->ob_width+1, ob->ob_height+1, selected);
  556.                 if (selected)
  557.                 {
  558.                     tx+=PUSH3D_DISTANCE; ty+=PUSH3D_DISTANCE;
  559.                 }
  560.                 vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  561.                 v_gtext(V_handle,tx,ty,textblk->te_ptext);
  562.             }else{
  563. /*                if (colourword->opaque)*/
  564.                 {
  565.                     coords[0]=parent_x+ob->ob_x;
  566.                     coords[1]=parent_y+ob->ob_y;
  567.                     coords[2]=coords[0]+ob->ob_width-1;
  568.                     coords[3]=coords[1]+ob->ob_height-1;
  569.                     v_bar(V_handle, coords);
  570.                 }
  571.                 
  572.                 vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  573.                 v_gtext(V_handle,tx,ty,textblk->te_ptext);
  574.  
  575.                 if (selected)
  576.                 {
  577.                     coords[0]=parent_x+ob->ob_x;
  578.                     coords[1]=parent_y+ob->ob_y;
  579.                     coords[2]=coords[0]+ob->ob_width-1;
  580.                     coords[3]=coords[1]+ob->ob_height-1;
  581.                     vswr_mode(V_handle,MD_XOR);
  582.                     vsf_color(V_handle,BLACK);
  583.                     vsf_interior(V_handle,FIS_SOLID);
  584.                     v_bar(V_handle, coords);
  585.                 }
  586.  
  587.                 if (border_thick)    /* Display a border? */
  588.                 {
  589.                     vswr_mode(V_handle, MD_REPLACE);
  590.                     draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y, 
  591.                                 ob->ob_width, ob->ob_height, 
  592.                                 border_thick, colourword->borderc);
  593.                 }
  594.             }
  595.             
  596.             if (ob->ob_state&IS_EDIT)
  597.             {
  598.                 coords[0]=parent_x+ob->ob_x+txt_curs*tw;
  599.                 coords[1]=parent_y+ob->ob_y;
  600.                 coords[2]=coords[0]+tw-1;
  601.                 coords[3]=coords[1]+th-1;
  602.                 vswr_mode(V_handle,MD_XOR);
  603.                 vsf_color(V_handle,BLACK);
  604.                 vsf_interior(V_handle,FIS_SOLID);
  605.                 v_bar(V_handle, coords);
  606.             }
  607.  
  608.             break;
  609.         case G_BUTTON:
  610.             tx=parent_x+ob->ob_x+(ob->ob_width/2);
  611.             if (ob->ob_flags&FLD3DANY)
  612.             {
  613.                 XA_3D_pushbutton(parent_x+ob->ob_x-1, parent_y+ob->ob_y-1, ob->ob_width+1, ob->ob_height+1, selected);
  614.                 if (selected)
  615.                 {
  616.                     tx+=PUSH3D_DISTANCE; ty+=PUSH3D_DISTANCE;
  617.                 }
  618.             }else{
  619.                 
  620.                 if (colourmode && selected)
  621.                 {
  622.                     coords[0]=parent_x+ob->ob_x+border_thick;
  623.                     coords[1]=parent_y+ob->ob_y+border_thick;
  624.                     coords[2]=coords[0]+ob->ob_width-border_thick*2-1;
  625.                     coords[3]=coords[1]+ob->ob_height-border_thick*2-1;
  626.                     vswr_mode(V_handle, MD_REPLACE);
  627.                     vsf_color(V_handle,BLACK);
  628.                     vsf_interior(V_handle,FIS_SOLID);
  629.                     v_bar(V_handle, coords);
  630.                     vst_color(V_handle,WHITE);
  631.                 
  632.                 }else{
  633.                     coords[0]=parent_x+ob->ob_x+border_thick;
  634.                     coords[1]=parent_y+ob->ob_y+border_thick;
  635.                     coords[2]=coords[0]+ob->ob_width-border_thick*2-1;
  636.                     coords[3]=coords[1]+ob->ob_height-border_thick*2-1;
  637.                     vswr_mode(V_handle, MD_REPLACE);
  638.                     vsf_color(V_handle,WHITE);
  639.                     vsf_interior(V_handle,FIS_SOLID);
  640.                     v_bar(V_handle, coords);
  641.                 
  642.                     draw_2d_box(parent_x+ob->ob_x, parent_y+ob->ob_y,
  643.                             ob->ob_width, ob->ob_height,
  644.                             border_thick, BLACK);
  645.                     vst_color(V_handle,BLACK);
  646.                 
  647.                 }
  648.             }
  649.             vst_font(V_handle,display.standard_font_id);
  650.             vst_point(V_handle,display.standard_font_point,&temp,&temp,&temp,&temp);
  651.             vswr_mode(V_handle, MD_TRANS);
  652.             vst_alignment(V_handle,1,5,&temp,&temp);
  653.             v_gtext(V_handle,tx,ty,(char*)ob->ob_spec);
  654.             break;
  655.         case G_STRING:
  656.             vst_font(V_handle,display.standard_font_id);
  657.             vst_point(V_handle,display.standard_font_point,&temp,&temp,&temp,&temp);
  658.             vswr_mode(V_handle, MD_TRANS);
  659.             vst_alignment(V_handle,0,5,&temp,&temp);
  660.             vst_color(V_handle, colourword->textc);
  661.             v_gtext(V_handle,parent_x+ob->ob_x,ty,(char*)ob->ob_spec);
  662.             break;
  663.         case G_FTEXT:
  664.             DIAGS(("G_FTEXT:\ntext=%s\n",textblk->te_ptext));
  665.             DIAGS(("template=%s\n",textblk->te_ptmplt));
  666.             if (textblk->te_pvalid)
  667.                 DIAGS(("valid=%s\n",textblk->te_pvalid));
  668.             
  669.             txt_curs=format_dialog_text(temp_text, textblk->te_ptmplt, textblk->te_ptext,textblk->te_tmplen);
  670.             vst_color(V_handle, colourword->textc);
  671.             vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  672.             switch(textblk->te_just)
  673.             {
  674.                 case 0:
  675.                     v_gtext(V_handle,parent_x+ob->ob_x,ty,temp_text);
  676.                     break;
  677.                 case 1:
  678.                     v_gtext(V_handle,parent_x+ob->ob_x+ob->ob_width,ty,temp_text);
  679.                     break;
  680.                 case 2:
  681.                     v_gtext(V_handle,parent_x+ob->ob_x+(ob->ob_width/2),ty,temp_text);
  682.                     break;
  683.             }
  684.             
  685.             if (ob->ob_state&IS_EDIT)
  686.             {
  687.                 coords[0]=parent_x+ob->ob_x+txt_curs*tw;
  688.                 coords[1]=parent_y+ob->ob_y;
  689.                 coords[2]=coords[0]+tw-1;
  690.                 coords[3]=coords[1]+th-1;
  691.                 vswr_mode(V_handle,MD_XOR);
  692.                 vsf_color(V_handle,BLACK);
  693.                 vsf_interior(V_handle,FIS_SOLID);
  694.                 v_bar(V_handle, coords);
  695.             }
  696.             
  697.             if (selected)
  698.             {
  699.                 coords[0]=parent_x+ob->ob_x;
  700.                 coords[1]=parent_y+ob->ob_y;
  701.                 coords[2]=coords[0]+ob->ob_width-1;
  702.                 coords[3]=coords[1]+ob->ob_height-1;
  703.                 vswr_mode(V_handle,MD_XOR);
  704.                 vsf_color(V_handle,BLACK);
  705.                 vsf_interior(V_handle,FIS_SOLID);
  706.                 v_bar(V_handle, coords);
  707.             }
  708.             
  709.             break;
  710.         case G_TEXT:
  711.             vst_color(V_handle, colourword->textc);
  712.             vswr_mode(V_handle, colourword->opaque ? MD_REPLACE:MD_TRANS);
  713.             switch(textblk->te_just)
  714.             {
  715.                 case 0:
  716.                     v_gtext(V_handle,parent_x+ob->ob_x,ty,textblk->te_ptext);
  717.                     break;
  718.                 case 1:
  719.                     v_gtext(V_handle,parent_x+ob->ob_x+ob->ob_width,ty,textblk->te_ptext);
  720.                     break;
  721.                 case 2:
  722.                     v_gtext(V_handle,parent_x+ob->ob_x+(ob->ob_width/2),ty,textblk->te_ptext);
  723.                     break;
  724.             }
  725.  
  726.             if (ob->ob_state&IS_EDIT)
  727.             {
  728.                 coords[0]=parent_x+ob->ob_x+txt_curs*tw;
  729.                 coords[1]=parent_y+ob->ob_y;
  730.                 coords[2]=coords[0]+tw-1;
  731.                 coords[3]=coords[1]+th-1;
  732.                 vswr_mode(V_handle,MD_XOR);
  733.                 vsf_color(V_handle,BLACK);
  734.                 vsf_interior(V_handle,FIS_SOLID);
  735.                 v_bar(V_handle, coords);
  736.             }
  737.  
  738.             if (selected)
  739.             {
  740.                 coords[0]=parent_x+ob->ob_x;
  741.                 coords[1]=parent_y+ob->ob_y;
  742.                 coords[2]=coords[0]+ob->ob_width-1;
  743.                 coords[3]=coords[1]+ob->ob_height-1;
  744.                 vswr_mode(V_handle,MD_XOR);
  745.                 vsf_color(V_handle,BLACK);
  746.                 vsf_interior(V_handle,FIS_SOLID);
  747.                 v_bar(V_handle, coords);
  748.             }
  749.             
  750.             break;
  751.         case G_CICON:        /* If t==G_CICON by we get here, we've definitely got a valid CICON for this res.... */
  752.             icx=parent_x+ob->ob_x+iconblk->ib_xicon;
  753.             icy=parent_y+ob->ob_y+iconblk->ib_yicon;
  754.             
  755.             coords[0]=coords[1]=0;
  756.             coords[2]=iconblk->ib_wicon-1; coords[3]=iconblk->ib_hicon-1;
  757.             coords[4]=icx; coords[5]=icy;
  758.             coords[6]=icx+iconblk->ib_wicon-1; coords[7]=icy+iconblk->ib_hicon-1;
  759.             
  760.             Micon.fd_w=iconblk->ib_wicon;
  761.             Micon.fd_h=iconblk->ib_hicon;
  762.             Micon.fd_wdwidth=(Micon.fd_w+15)>>4;
  763.             Micon.fd_nplanes=1;
  764.             Micon.fd_stand=0;
  765.             Mscreen.fd_addr=NULL;
  766.             
  767.             if (selected)
  768.             {
  769.                 Micon.fd_addr=this_cicon->sel_mask;
  770.             }else{
  771.                 Micon.fd_addr=this_cicon->col_mask;
  772.             }
  773.             cols[0]=1; cols[0]=0;
  774.             vrt_cpyfm(V_handle, MD_TRANS, coords, &Micon, &Mscreen, cols);
  775.  
  776.             if (selected)
  777.             {
  778.                 Micon.fd_addr=this_cicon->sel_data;
  779.             }else{
  780.                 Micon.fd_addr=this_cicon->col_data;
  781.             }
  782.             Micon.fd_nplanes=display.planes;
  783.             
  784.             vro_cpyfm(V_handle, S_OR_D, coords, &Micon, &Mscreen);
  785.             break;
  786.  
  787.         case G_ICON:
  788.             icx=parent_x+ob->ob_x+iconblk->ib_xicon;
  789.             icy=parent_y+ob->ob_y+iconblk->ib_yicon;
  790.             
  791.             coords[0]=coords[1]=0;
  792.             coords[2]=iconblk->ib_wicon-1; coords[3]=iconblk->ib_hicon-1;
  793.             coords[4]=icx; coords[5]=icy;
  794.             coords[6]=icx+iconblk->ib_wicon-1; coords[7]=icy+iconblk->ib_hicon-1;
  795.             
  796.             Micon.fd_w=iconblk->ib_wicon;
  797.             Micon.fd_h=iconblk->ib_hicon;
  798.             Micon.fd_wdwidth=(Micon.fd_w+15)>>4;
  799.             Micon.fd_nplanes=1;
  800.             Micon.fd_stand=0;
  801.             Mscreen.fd_addr=NULL;
  802.             
  803.             Micon.fd_addr=iconblk->ib_pmask;
  804.             if (selected)
  805.             {
  806.                 icn_col=((iconblk->ib_char)>>8)&0xf;
  807.                 msk_col=((iconblk->ib_char)>>12)&0xf;
  808.             }else{
  809.                 icn_col=((iconblk->ib_char)>>12)&0xf;
  810.                 msk_col=((iconblk->ib_char)>>8)&0xf;
  811.             }
  812.             
  813.             cols[0]=msk_col;
  814.             cols[1]=icn_col;
  815.             vrt_cpyfm(V_handle, MD_TRANS, coords, &Micon, &Mscreen, cols);
  816.             
  817.             Micon.fd_addr=iconblk->ib_pdata;
  818.             cols[0]=icn_col;
  819.             cols[1]=msk_col;
  820.             vrt_cpyfm(V_handle, MD_TRANS, coords, &Micon, &Mscreen, cols);
  821.             
  822.             vst_color(V_handle, icn_col);
  823.             vswr_mode(V_handle, MD_REPLACE);
  824.             vst_font(V_handle,display.small_font_id);
  825.             vst_point(V_handle,display.small_font_point,&temp,&temp,&temp,&temp);
  826.             v_gtext(V_handle, icx+iconblk->ib_xtext, icy+iconblk->ib_ytext,iconblk->ib_ptext);
  827.             break;
  828.             
  829.         case G_IMAGE:
  830.             icx=parent_x+ob->ob_x;
  831.             icy=parent_y+ob->ob_y;
  832.  
  833.             Micon.fd_w=(bitblk->bi_wb)<<3;
  834.             Micon.fd_h=bitblk->bi_hl;
  835.             Micon.fd_wdwidth=(Micon.fd_w+15)>>4;
  836.             Micon.fd_nplanes=1;
  837.             Micon.fd_stand=0;
  838.             Mscreen.fd_addr=NULL;
  839.             
  840.             Micon.fd_addr=bitblk->bi_pdata;
  841.             cols[0]=colourword->fillc;
  842.             cols[1]=0;
  843.             
  844.             coords[0]=bitblk->bi_x;
  845.             coords[1]=bitblk->bi_y;
  846.             coords[2]=Micon.fd_w-1-coords[0]; coords[3]=Micon.fd_h-1-coords[1];
  847.             coords[4]=icx; coords[5]=icy;
  848.             coords[6]=icx+Micon.fd_w-1-coords[0]; coords[7]=icy+Micon.fd_h-1-coords[1];
  849.             vrt_cpyfm(V_handle, MD_TRANS, coords, &Micon, &Mscreen, cols);
  850.             break;
  851.     }
  852.  
  853.     if (ob->ob_state&CROSSED)
  854.     {
  855.         vsl_color(V_handle,colourword->borderc);
  856.         coords[0]=parent_x+ob->ob_x;
  857.         coords[1]=parent_y+ob->ob_y;
  858.         coords[2]=parent_x+ob->ob_x+ob->ob_width-1;
  859.         coords[3]=parent_y+ob->ob_y+ob->ob_height-1;
  860.         v_pline(V_handle,2,coords);
  861.         coords[0]=parent_x+ob->ob_x+ob->ob_width-1;
  862.         coords[2]=parent_x+ob->ob_x;
  863.         v_pline(V_handle,2,coords);
  864.     }
  865.     
  866.     /* Handle CHECKED object state: */
  867.     if ( ob->ob_state & state_mask & CHECKED )
  868.     {
  869.         vst_font(V_handle,display.standard_font_id);
  870.         vst_point(V_handle,display.standard_font_point,&temp,&temp,&temp,&temp);
  871.         vswr_mode(V_handle, MD_TRANS);
  872.         vst_alignment(V_handle,0,5,&temp,&temp);
  873.         vst_color(V_handle, BLACK);
  874.         v_gtext(V_handle, obx+2, oby, "\10");    /* ASCII 8 = checkmark */
  875.     }
  876.  
  877.     /* Handle CROSSED object state: */
  878.     if ( ob->ob_state & state_mask & CROSSED )
  879.     {
  880.         coords[0]=coords[4]=obx-border_thick;
  881.         coords[1]=coords[7]=oby-border_thick;
  882.         coords[2]=coords[6]=obx2+border_thick;
  883.         coords[3]=coords[5]=oby2+border_thick;
  884.  
  885.         vswr_mode(V_handle, MD_TRANS);
  886.         vsl_color(V_handle, WHITE);
  887.         vsl_width(V_handle, 1);
  888.         vsl_type(V_handle, 1);
  889.         v_pline(V_handle, 2, &coords[0]);
  890.         v_pline(V_handle, 2, &coords[4]);
  891.     }
  892.  
  893.     coords[0]=obx;
  894.     coords[1]=oby;
  895.     coords[2]=obx2;
  896.     coords[3]=oby2;
  897.     if (border_thick > 0)        /* Inside border */
  898.     {
  899.         coords[0]+=border_thick;
  900.         coords[1]+=border_thick;
  901.         coords[2]-=border_thick;
  902.         coords[3]-=border_thick;
  903.     }
  904.  
  905.     /* Handle DISABLED state: */
  906.     /* (May not look too hot in colour mode, but it's better than
  907.         no disabling at all...) */
  908.     if ( ob->ob_state & state_mask & DISABLED )
  909.     {
  910.         static short pattern[16]={
  911.             0x5555, 0xaaaa, 0x5555, 0xaaaa,
  912.             0x5555, 0xaaaa, 0x5555, 0xaaaa,
  913.             0x5555, 0xaaaa, 0x5555, 0xaaaa,
  914.             0x5555, 0xaaaa, 0x5555, 0xaaaa };
  915.  
  916.         vswr_mode(V_handle, MD_TRANS);
  917.         vsf_color(V_handle, WHITE);
  918.         vsf_udpat(V_handle, pattern, 1);
  919.         vsf_interior(V_handle, FIS_USER);
  920.         vr_recfl(V_handle, coords);
  921.     }
  922.  
  923.     /* Handle SELECTED state only in non-colour mode: */
  924.     if (!colourmode && selected && (state_mask&SELECTED))
  925.     {
  926.         vswr_mode(V_handle, MD_XOR);
  927.         vsf_color(V_handle, BLACK);
  928.         vsf_interior(V_handle, FIS_SOLID);
  929.         vr_recfl(V_handle, coords);
  930.     }
  931.  
  932.     vswr_mode(V_handle,MD_TRANS);
  933. }
  934.  
  935. /*
  936.     Walk an object tree, calling display for each object
  937. */
  938. short draw_object_tree(OBJECT *tree, short object, short depth)
  939. {
  940.     short next;
  941.     short current=0,rel_depth=1,head;
  942.     short x=0,y=0,start_drawing=FALSE;
  943.     
  944.     depth++;
  945.     
  946.     do {
  947.         
  948.         if (current==object)
  949.         {
  950.             start_drawing=TRUE;
  951.             rel_depth=0;
  952.         }
  953.         
  954.         if ((start_drawing)&&(!(tree[current].ob_flags&HIDETREE)))
  955.         {
  956.             display_object(tree,current,x,y);    /* Display this object */
  957.         }
  958.  
  959.         head=tree[current].ob_head;
  960.                                         /* Any non-hidden children? */
  961.         if (((head!=-1)&&(!(tree[current].ob_flags&HIDETREE)))
  962.             &&((!start_drawing)||((start_drawing)&&(rel_depth<depth))))
  963.         {
  964.         
  965.             x+=tree[current].ob_x; y+=tree[current].ob_y;
  966.             rel_depth++;
  967.             current=head;
  968.         
  969.         }else{
  970.  
  971.             next=tree[current].ob_next;        /* Try for a sibling */
  972.     
  973.             while((next!=-1)                /* Trace back up tree if no more siblings */
  974.                     &&(tree[next].ob_tail==current))
  975.             {
  976.                 current=next;
  977.                 x-=tree[current].ob_x;
  978.                 y-=tree[current].ob_y;
  979.                 next=tree[current].ob_next;
  980.                 rel_depth--;
  981.             }
  982.             current=next;
  983.         }
  984.     
  985.     }while((current!=-1)&&(!((start_drawing)&&(rel_depth<1))));
  986.  
  987.     vst_alignment(V_handle,0,5,&x,&x);
  988.     vswr_mode(V_handle, MD_TRANS);
  989.     vst_font(V_handle,display.standard_font_id);
  990.     vst_point(V_handle,display.standard_font_point,&next,&next,&next,&next);
  991.     vsf_interior(V_handle, FIS_SOLID);
  992.  
  993.     return TRUE;
  994. }
  995.  
  996. /*
  997.     Get the true screen coords of an object
  998. */
  999. short object_abs_coords(OBJECT *tree, short object, short *obx, short *oby)
  1000. {
  1001.     short next;
  1002.     short current=0;
  1003.     short x=0,y=0;
  1004.     
  1005.     do {
  1006.         if (current==object)    /* Found the object in the tree? cool, return the coords */
  1007.         {
  1008.             *obx=x+tree[current].ob_x;
  1009.             *oby=y+tree[current].ob_y;
  1010.             return 1;
  1011.         }
  1012.         
  1013.         if (tree[current].ob_head!=-1)        /* Any children? */
  1014.         {
  1015.             x+=tree[current].ob_x; y+=tree[current].ob_y;
  1016.             current=tree[current].ob_head;
  1017.         }else{
  1018.             next=tree[current].ob_next;                            /* Try for a sibling */
  1019.  
  1020.             while((next!=-1)&&(tree[next].ob_tail==current))    /* Trace back up tree if no more siblings */
  1021.             {
  1022.                 current=next;
  1023.                 x-=tree[current].ob_x;
  1024.                 y-=tree[current].ob_y;
  1025.                 next=tree[current].ob_next;
  1026.             }
  1027.             current=next;
  1028.         }
  1029.     } while(current!=-1);        /* If 'current' is -1 then we have finished */
  1030.  
  1031.     return 0;    /* Bummer - didn't find the object, so return error */
  1032. }
  1033.  
  1034. /*
  1035.     Find which object is at a given location
  1036. */
  1037. short find_object(OBJECT *tree, short object, short depth, short obx, short oby)
  1038. {
  1039.     short next;
  1040.     short current=0,rel_depth=1;
  1041.     short x=0,y=0,start_checking=FALSE;
  1042.     short pos_object=-1;
  1043.     
  1044.     do {
  1045.         if (current==object)    /* We can start considering objects at this point */
  1046.         {
  1047.             start_checking=TRUE;
  1048.             rel_depth=0;
  1049.         }
  1050.         
  1051.         if (start_checking)
  1052.         {
  1053.             if ((tree[current].ob_x+x<=obx)
  1054.                 &&((tree[current].ob_y+y<=oby)
  1055.                 &&((tree[current].ob_x+x+tree[current].ob_width>=obx)
  1056.                 &&(tree[current].ob_y+y+tree[current].ob_height>=oby))))
  1057.             {
  1058.                 pos_object=current;    /* This is only a possible object, as it may have children on top of it. */
  1059.             }
  1060.         }
  1061.  
  1062.         if (((!start_checking)||(rel_depth<depth))&&(tree[current].ob_head!=-1))        /* Any children? */
  1063.         {
  1064.             x+=tree[current].ob_x; y+=tree[current].ob_y;
  1065.             rel_depth++;
  1066.             current=tree[current].ob_head;
  1067.         }else{
  1068.             next=tree[current].ob_next;                            /* Try for a sibling */
  1069.  
  1070.             while((next!=-1)&&(tree[next].ob_tail==current))    /* Trace back up tree if no more siblings */
  1071.             {
  1072.                 current=next;
  1073.                 x-=tree[current].ob_x;
  1074.                 y-=tree[current].ob_y;
  1075.                 next=tree[current].ob_next;
  1076.                 rel_depth--;
  1077.             }
  1078.             current=next;
  1079.         }
  1080.         
  1081.     } while((current!=-1)&&(rel_depth>0));
  1082.  
  1083.     return pos_object;
  1084. }
  1085.  
  1086. /*
  1087.     Perform a few fixes on a menu tree prior to installing it
  1088.     (ensure title spacing & items fit into their menus)
  1089. */
  1090. void fix_menu(OBJECT *root)
  1091. {
  1092.     short pxy[8];
  1093.     short title,mnx=0,mnh,mnw,temp;
  1094.     short surround,text;
  1095.  
  1096.     title=root[root[root[0].ob_head].ob_head].ob_head;
  1097.     surround=root[root[0].ob_tail].ob_head;
  1098.     
  1099.     while(title!=root[root[0].ob_head].ob_head)        /* Fix title spacings (some resource editors don't set them up right) */
  1100.     {
  1101.         root[title].ob_x=mnx;
  1102.         root[surround].ob_x=mnx;
  1103.  
  1104.         vqt_extent(V_handle,(char*)root[title].ob_spec,pxy);
  1105.         mnw=(abs(pxy[2]-pxy[0])+4);
  1106.         mnx+=mnw;
  1107.         root[title].ob_width=mnw;
  1108.         root[title].ob_height=display.c_max_h;
  1109.  
  1110.         mnw=mnh=0;
  1111.         
  1112.         for(text=root[surround].ob_head; text!=surround; text=root[text].ob_next)
  1113.         {
  1114.             vqt_extent(V_handle,(char*)root[text].ob_spec,pxy);
  1115.             temp=abs(pxy[2]-pxy[0]);
  1116.  
  1117.             if (temp>mnw)
  1118.                 mnw=temp;
  1119.                 
  1120.             mnh+=display.c_max_h;
  1121.         }
  1122.         
  1123.         root[surround].ob_width=mnw;
  1124.         root[surround].ob_height=mnh;
  1125.  
  1126.         title=root[title].ob_next;
  1127.         surround=root[surround].ob_next;
  1128.     }
  1129.     
  1130.     root[0].ob_width=mnx;
  1131.     root[0].ob_height=display.c_max_h;
  1132.     root[root[0].ob_head].ob_width=mnx;
  1133.     root[root[0].ob_head].ob_height=display.c_max_h;
  1134.     root[root[0].ob_tail].ob_width=mnx;
  1135.     root[root[0].ob_tail].ob_height=display.c_max_h;
  1136. }
  1137.